﻿namespace Koala.Pro.Common
{
    public static class AbpTypeExtensions
    {
        public static string GetFullNameWithAssemblyName(this Type type)
        {
            return type.FullName + ", " + type.Assembly.GetName().Name;
        }

        public static bool IsAssignableTo<TTarget>(this Type type)
        {
            Check.NotNull(type, "type");
            return IsAssignableTo(type, typeof(TTarget));
        }

        public static bool IsAssignableTo(this Type type, Type targetType)
        {
            Check.NotNull(type, "type");
            Check.NotNull(targetType, "targetType");
            return targetType.IsAssignableFrom(type);
        }

        public static Type[] GetBaseClasses(this Type type, bool includeObject = true)
        {
            Check.NotNull(type, "type");
            List<Type> list = new List<Type>();
            AddTypeAndBaseTypesRecursively(list, type.BaseType, includeObject);
            return list.ToArray();
        }

        public static Type[] GetBaseClasses(this Type type, Type stoppingType, bool includeObject = true)
        {
            Check.NotNull(type, "type");
            List<Type> list = new List<Type>();
            AddTypeAndBaseTypesRecursively(list, type.BaseType, includeObject, stoppingType);
            return list.ToArray();
        }

        private static void AddTypeAndBaseTypesRecursively(List<Type> types, Type type, bool includeObject, Type stoppingType = null)
        {
            if (!(type == null) && !(type == stoppingType) && (includeObject || !(type == typeof(object))))
            {
                AddTypeAndBaseTypesRecursively(types, type.BaseType, includeObject, stoppingType);
                types.Add(type);
            }
        }
    }
}
